import { Node, Edge, Position, MarkerType } from "@vue-flow/core";
import { inputType } from "./serviceDict";
import axios from "axios";

interface NodePosition {
  x: number;
  y: number;
}

//创建新节点
const createNewNode = (id: string, type: "input" | "output", data: any, position: NodePosition = { x: 0, y: 0 }): Node => {
  return {
    id,
    type,
    data: {
      ...data,
      toolbarPosition: type === "input" ? Position.Right : Position.Left
    },
    position
  };
};

// 创建新边

const createNewEdge = (source: string, target: string, isDefaultFlow: boolean = false): Edge => {
  return {
    id: `e${source}-${target}`,
    source,
    target,
    // 如果是默认流程（工序之间的连接），使用上下handler；否则使用左右handler
    sourceHandle: isDefaultFlow ? "bottom" : "right",
    targetHandle: isDefaultFlow ? "top" : "left",
    type: "",
    markerEnd: {
      type: MarkerType.ArrowClosed,
      color: "#999999"
    },
    style: {
      stroke: "#999999",
      strokeWidth: 1
    }
  };
};

//重新排列所有输入/输出节点
const realignIONodes = (nodes: Node[], edges: Edge[], parentNodeId: string) => {
  const parentNode = nodes.find(node => node.id === parentNodeId);
  if (!parentNode) return;

  const connectedNodes = edges
    .filter(edge => edge.source === parentNodeId || edge.target === parentNodeId)
    .map(edge => {
      const nodeId = edge.source === parentNodeId ? edge.target : edge.source;
      return nodes.find(node => node.id === nodeId);
    })
    .filter((node): node is Node => node !== undefined);

  const inputNodes = connectedNodes.filter(node => node.type === "input");
  const outputNodes = connectedNodes.filter(node => node.type === "output");

  const spacingY = 43; // 节点之间的垂直间距
  const spacingX = 300; // 水平间距
  const centerOffsetY = 12;
  const inputOffsetX = 250; // 减小输入节点的水平偏移

  // 计算输入节点位置
  if (inputNodes.length > 0) {
    const totalHeight = (inputNodes.length - 1) * spacingY;
    const startY = parentNode.position.y - totalHeight / 2 + centerOffsetY;

    inputNodes.forEach((node, index) => {
      node.position = {
        x: parentNode.position.x + inputOffsetX, // 使用较小的水平偏移
        y: startY + index * spacingY
      };
    });
  }

  // 计算输出节点位置
  if (outputNodes.length > 0) {
    const totalHeight = (outputNodes.length - 1) * spacingY;
    const startY = parentNode.position.y - totalHeight / 2 + centerOffsetY; // 添加偏移量

    outputNodes.forEach((node, index) => {
      node.position = {
        x: parentNode.position.x - spacingX,
        y: startY + index * spacingY
      };
    });
  }
};

/**
 * 创建默认节点
 */
const createDefaultNode = (
  id: string,
  processData: any,
  position: NodePosition = { x: 0, y: 0 },
  options: {
    isEmission?: number;
  } = {}
): Node => {
  const { isEmission = 1 } = options;

  return {
    id,
    type: "default",
    data: {
      id: processData?.id || "",
      label: processData?.processName || "未知工序",
      processId: processData?.processId || "",
      description: processData?.description || "",
      createTime: processData?.createTime || "",
      isEmission, // 使用传入的 isEmission
      isTransport: processData?.isTransport ?? 0,
      equipments: processData?.equipments || [],
      toolbarPosition: Position.Bottom
    },
    position,
    sourcePosition: Position.Bottom,
    targetPosition: Position.Top
  };
};

/**
 * 初始化流程图的节点和边
 */
const initializeFlowChart = (
  processes: {
    id: string;
    processId: string;
    processName: string;
    description: string;
    createTime: string;
    equipmentName?: string;
    equipments?: { equipmentId: number }[];
  }[],
  options: {
    spacing?: number;
    isEmission?: number;
  } = {}
): { nodes: Node[]; edges: Edge[] } => {
  const { spacing = 170, isEmission = 1 } = options;
  const nodes: Node[] = [];
  const edges: Edge[] = [];

  // 创建节点
  processes.forEach((process, index) => {
    const nodePosition = {
      x: 300,
      y: index * spacing
    };

    const node = createDefaultNode((index + 1).toString(), process, nodePosition, { isEmission });
    nodes.push(node);

    // 创建与前一个节点的连接
    if (index > 0) {
      const edge = createNewEdge(index.toString(), (index + 1).toString(), true);
      edges.push(edge);
    }
  });

  return { nodes, edges };
};

//  从已保存的流程图数据初始化输入输出节点
const initializeIONodes = (
  projectId: string,
  typeId: string,
  id: string,
  currentNodes: Node[],
  currentEdges: Edge[],
  flowChartList: any[],
  options: {
    isProcessFlow?: boolean; // 是否是工艺流程界面
  } = {}
): { nodes: Node[]; edges: Edge[] } => {
  const { isProcessFlow = false } = options;
  const newNodes = [...currentNodes];
  const newEdges = [...currentEdges];

  let existingFlowChart;

  // 直接使用传入的 flowChartList
  existingFlowChart = { nodes: flowChartList };

  if (!existingFlowChart?.nodes) return { nodes: newNodes, edges: newEdges };

  // 初始化输入输出节点
  existingFlowChart.nodes.forEach((flowNode: { nodeId: string; inputNodes: any[]; outputNodes: any[] }) => {
    const defaultNode = newNodes.find(node => node.id === flowNode.nodeId);
    if (!defaultNode) return;

    // 添加输入节点
    flowNode.inputNodes.forEach((input: any) => {
      const newNodeId = (Math.max(...newNodes.map(node => parseInt(node.id))) + 1).toString();

      const inputNode: Node = {
        id: newNodeId,
        type: "output",
        data: {
          label: input.inputType,

          consumption: input.inputConsumption,
          unit: input.inputUnit,
          dataSource: input.dataSource,
          equipmentId: input.equipmentId,

          toolbarPosition: Position.Left,
          isEmission: isProcessFlow ? 0 : 1
        },
        position: {
          x: input.XLocation,
          y: input.YLocation
        }
      };

      newNodes.push(inputNode);
      newEdges.push(createNewEdge(inputNode.id, defaultNode.id));
    });

    // 添加输出节点
    flowNode.outputNodes.forEach((output: any) => {
      const newNodeId = (Math.max(...newNodes.map(node => parseInt(node.id))) + 1).toString();

      const outputNode: Node = {
        id: newNodeId,
        type: "input",
        data: {
          label: output.outputName,
          output: output.outputType,

          consumption: output.outputConsumption,
          unit: output.outputUnit,

          toolbarPosition: Position.Right,
          isEmission: isProcessFlow ? 0 : 1
        },
        position: {
          x: output.XLocation,
          y: output.YLocation
        }
      };

      newNodes.push(outputNode);
      newEdges.push(createNewEdge(defaultNode.id, outputNode.id));
    });
  });
  console.log("初始化输入输出节点完成！handler", newNodes, newEdges);
  return { nodes: newNodes, edges: newEdges };
};

// 获取节点的连接节点
const getConnectedNodes = (defaultNode: Node, nodes: Node[], edges: Edge[], type?: "input" | "output"): Node[] => {
  const connectedNodes = edges
    .filter(edge => edge.source === defaultNode.id || edge.target === defaultNode.id)
    .map(edge => {
      const nodeId = edge.source === defaultNode.id ? edge.target : edge.source;
      return nodes.find(node => node.id === nodeId);
    })
    .filter((node): node is Node => node !== undefined);

  return type ? connectedNodes.filter(node => node.type === type) : connectedNodes;
};

/**
 * 收集节点的输入输出标签
 */
const collectNodeLabels = (defaultNode: Node, nodes: Node[], edges: Edge[]): string[] => {
  const inputLabels = getConnectedNodes(defaultNode, nodes, edges, "output")
    .map(node => {
      const inputValue = node.data?.label;
      return inputType.find(type => type.value === inputValue)?.label || node.data?.label || "";
    })
    .filter(Boolean);

  const outputLabels = getConnectedNodes(defaultNode, nodes, edges, "input")
    .map(node => node.data?.label || "")
    .filter(Boolean);

  return [...inputLabels, ...outputLabels];
};

/**
 * 更新碳排源清单[碳排源名称]
 */
const updateEmissionList = async (projectId: number, materialId: string, labels: string[]): Promise<void> => {
  const combinedLabels = labels.join("、");
  console.log("materialIdsave", materialId);
  const baseUrl = import.meta.env.VITE_BASE_URL;

  try {
    if (materialId === "0") {
      // 装配排放更新
      const assemblyPayload = {
        projectId,
        emissionList: [{ emissions: combinedLabels }]
      };
      console.log("装配排放更新:", assemblyPayload);
      await axios.post(`${baseUrl}/api/carbon/updateAssemblyEmission`, assemblyPayload);
    } else {
      // 自制物料排放更新
      const materialPayload = {
        projectId,
        emissionList: [{ materialId: Number(materialId), emissions: combinedLabels }]
      };
      console.log("自制物料排放更新:", materialPayload);
      await axios.post(`${baseUrl}/api/carbon/updateEmissions`, materialPayload);
    }
  } catch (error) {
    console.error("更新排放源失败:", error);
  }
};

/**
 * 构建流程图数据
 */
const buildFlowChartData = (
  defaultNodes: Node[],
  nodes: Node[],
  edges: Edge[],
  projectId: number,
  typeId: string,
  id: string
) => {
  return {
    projectId,
    objectId: id,
    objectType: typeId,
    nodes: defaultNodes.map(defaultNode => ({
      nodeId: defaultNode.id,
      process: {
        id: defaultNode.data.id,
        processId: defaultNode.data.processId,
        processName: defaultNode.data.label,
        description: defaultNode.data.description,
        createTime: defaultNode.data.createTime
      },
      equipments: defaultNode.data.equipments || [],
      inputNodes: getConnectedNodes(defaultNode, nodes, edges, "output").map(node => ({
        inputType: node.data?.label || "",
        inputConsumption: Number(node.data?.consumption) || 0,
        inputUnit: node.data?.unit || 0,
        dataSource: node.data?.dataSource || "",
        equipmentId: Number(node.data?.equipmentId) || 0,
        XLocation: node.position.x,
        YLocation: node.position.y
      })),
      outputNodes: getConnectedNodes(defaultNode, nodes, edges, "input").map(node => ({
        outputType: node.data?.output || "",
        outputConsumption: Number(node.data?.consumption) || 0,
        outputName: node.data?.label || "",
        outputUnit: node.data?.unit || 0,
        XLocation: node.position.x,
        YLocation: node.position.y
      }))
    }))
  };
};

/**
 * 更新 flowChartList 数据
 */
const updateFlowChartList = (flowChartData: any, projectId: number, typeId: string, id: string, flowChartList: any[]): void => {
  const existingIndex = flowChartList.findIndex(
    item => item.projectId === projectId && item.objectId === id && item.objectType === typeId
  );

  if (existingIndex !== -1) {
    flowChartList[existingIndex] = flowChartData;
  } else {
    flowChartList.push(flowChartData);
  }
};

/**
 * 保存流程图数据
 */
const saveFlowChart = async (
  nodes: Node[],
  edges: Edge[],
  projectId: number,
  typeId: string,
  id: string,
  flowChartList: any[],
  options: {
    isProcessFlow?: boolean; // 是否是工艺流程界面
  } = {}
): Promise<void> => {
  try {
    const defaultNodes = nodes.filter(node => node.type === "default");
    console.log("开始保存流程图handlerrrr...");

    // 只在 selfMadeEmission 界面执行收集标签和更新排放清单
    if (!options.isProcessFlow) {
      const allNodeLabels = defaultNodes
        .map(defaultNode => collectNodeLabels(defaultNode, nodes, edges))
        .flat()
        .filter((value, index, self) => self.indexOf(value) === index);
      // 更新排放清单
      await updateEmissionList(projectId, id, allNodeLabels);
    }

    // 构建流程图数据
    const flowChartData = buildFlowChartData(defaultNodes, nodes, edges, projectId, typeId, id);
    console.log("flowChartDatasave", flowChartData);
    // 调用后端接口保存数据
    const baseUrl = import.meta.env.VITE_BASE_URL;
    const res = await axios.post(`${baseUrl}/api/carbon/saveFlowchart`, flowChartData);
    if (res.status !== 200 || res.data?.code !== 200) {
      throw new Error(res.data?.msg || "保存失败");
    }

    console.log("保存成功");
  } catch (error) {
    console.error("保存流程图数据时出错:", error);
    throw new Error("保存失败");
  }
};

// 更新导出
export {
  createNewNode,
  createNewEdge,
  createDefaultNode,
  initializeFlowChart,
  initializeIONodes,
  realignIONodes,
  saveFlowChart,
  getConnectedNodes,
  updateFlowChartList
};
